/*
 * Copyright 2009 Original Author(s)
 * 
 * This file is part of Kommando
 * 
 * Kommando is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * Kommando is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with Kommando.  If not, see <http://www.gnu.org/licenses/>.
 */
package org.kommando.core.selector;

import java.util.Collections;
import java.util.List;

import javax.swing.Icon;

import org.kommando.core.action.Action;
import org.kommando.core.action.ActionExecutionException;
import org.kommando.core.catalog.CatalogObject;
import org.kommando.core.command.Command;
import org.kommando.core.command.CommandContext;
import org.kommando.core.command.CommandExecutionException;
import org.kommando.core.util.Assert;

/**
 * {@link Command} implementation for executing an {@link Action} for a direct {@link CatalogObject} and an optional indirect {@link CatalogObject}.
 * 
 * @author Peter De Bruycker
 */
public class ActionCommand implements Command {
    private CatalogObject direct;
    private Action action;
    private CatalogObject indirect;

    public ActionCommand(CatalogObject direct, Action action, CatalogObject indirect) {
        Assert.argumentNotNull("direct", direct);
        Assert.argumentNotNull("action", action);

        this.direct = direct;
        this.action = action;
        this.indirect = indirect;
    }

    public ActionCommand(CatalogObject direct, Action action) {
        this(direct, action, null);
    }

    @Override
    public String getId() {
        StringBuilder sb = new StringBuilder();

        sb.append("command:");
        sb.append("(").append(direct.getId()).append(")");
        sb.append("(").append(action.getId()).append(")");
        if (indirect != null) {
            sb.append("(").append(indirect.getId()).append(")");
        }

        return sb.toString();
    }

    public void execute(CommandContext context) throws CommandExecutionException {
        try {
            List<CatalogObject> directObjects = Collections.singletonList(direct);
            List<CatalogObject> indirectObjects = indirect == null ? Collections.<CatalogObject> emptyList() : Collections
                    .<CatalogObject> singletonList(indirect);

            List<CatalogObject> results = action.execute(directObjects, indirectObjects);

            if (!results.isEmpty()) {
                // TODO pass all results
                context.setResult(results.get(0));
            }
        } catch (ActionExecutionException e) {
            throw new CommandExecutionException(e);
        }
    }

    @Override
    public Icon getIcon() {
        return action.getIcon();
    }

    @Override
    public String getDescription() {
        return getName();
    }

    @Override
    public String getName() {
        StringBuilder sb = new StringBuilder();

        sb.append(direct.getName());
        sb.append(" (").append(action.getName()).append(")");
        if (indirect != null) {
            sb.append(" ").append(indirect.getName());
        }

        return sb.toString();
    }

    public CatalogObject getDirect() {
        return direct;
    }

    public Action getAction() {
        return action;
    }

    public CatalogObject getIndirect() {
        return indirect;
    }
}
